home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
int24.arc
/
INT24.PAS
Wrap
Pascal/Delphi Source File
|
1985-03-05
|
7KB
|
201 lines
{ Thanks to Marshall Brain for the original code for this routine.
These routines provide a method for Turbo Pascal programs to trap MS-DOS
interrupt 24. INT 24 is called by DOS when a 'critical error' occurs, and
it normally prints the familiar "Abort, Retry, Ignore?" message.
With the INT 24 handler installed, errors of this type will be passed on to
Turbo Pascal as an error. If I/O checking is on, this will cause a program
crash. If I/O checking is off, IOResult will return an error code. The
global variable INT24Err will be true if an INT 24 error has occurred. The
variable INT24ErrorCode will contain the INT 24 error code as given by DOS.
These errors can be found in the DOS Technical Reference Manual. They
correspond to the error codes returned by the function INT24Result, with an
offset of 256. INT24Result is used like IOResult, and calls IOResult. It
then checks INT24Err, and if it is true, returns INT24ErrorCode+256 instead.
In most cases, INT24Result should be used, because INT24Err must be set back
to false, and because DOS sometimes restores its normal INT 24 handler after
an error.
Note that Turbo's normal IOResult codes for MS-DOS DO NOT correspond to the
I/O error numbers given in Appendix I of the Turbo Pascal manual, or to the
error codes given in the I/O error nn, PC=aaaa/Program aborted message. Here
is a table of the correspondence (all numbers in hexadecimal):
IOResult Turbo error
-------- -------------------------------------------------
00 00 none
01 90 record length mismatch
02 01 file does not exist
03 F1 directory is full
04 FF file disappeared
05 02 file not open for input
06 03 file not open for output
07 99 unexpected end of file
08 F0 disk write error
09 10 error in numeric format
0A 99 unexpected end of file
0B F2 file size overflow
0C 99 unexpected end of file
0D F0 disk write error
0E 91 seek beyond end of file
0F 04 file not open
10 20 operation not allowed on a logical device
11 21 not allowed in direct mode
12 22 assign to standard files is not allowed
- Bela Lubkin
}
Const
INT24Err: Boolean=False;
INT24ErrCode: Byte=0;
OldINT24: Array [1..2] Of Integer=(0,0);
Var
RegisterSet: Record Case Integer Of
1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
End;
Procedure INT24;
Begin
{To understand this routine, you will need to read}
{the description on Interrupt 24 in the DOS manual}
Inline
($83/$C4/$0A); {ADD SP,0AH Discard first 5 words on stack}
INT24Err:=True;
Inline
($89/$F8/ {MOV AX,DI Get INT 24 error code}
$2E/$A2/INT24ErrCode/ {MOV CS:[INT24ErrCode],AL}
$58/ {POP AX Pop all registers}
$B0/$FF/ {MOV AL,0FFH Set error flag}
$5B/ {POP BX}
$59/ {POP CX}
$5A/ {POP DX}
$5E/ {POP SI}
$5F/ {POP DI}
$5D/ {POP BP}
$1F/ {POP DS}
$07/ {POP ES}
$CF); {IRET Return to next instruction}
End;
Procedure INT24On; {Enable INT 24 trapping}
Begin
INT24Err:=False;
With RegisterSet Do
Begin
AX:=$3524;
MsDos(RegisterSet);
If (OldINT24[1] Or OldINT24[2])=0 Then
Begin
OldINT24[1]:=ES;
OldINT24[2]:=BX;
End;
DS:=CSeg;
DX:=Ofs(INT24);
AX:=$2524;
MsDos(RegisterSet);
End;
End;
Procedure INT24Off; {Disable INT 24 trapping. Should be done at the end
of the program, if you plan to be running the program
from within Turbo.}
Begin
INT24Err:=False;
If OldINT24[1]<>0 Then
With RegisterSet Do
Begin
DS:=OldINT24[1];
DX:=OldINT24[2];
AX:=$2524;
MsDos(RegisterSet);
End;
OldINT24[1]:=0;
OldINT24[2]:=0;
End;
Function INT24Result: Integer;
Var
I:Integer;
Begin
I:=IOResult;
If INT24Err Then
Begin
I:=I+256*INT24ErrCode;
INT24On;
End;
INT24Result:=I;
End;
{ INT24Result returns all the regular Turbo IOResult codes if no critical
error has occurred. If a critical error, then the following values are
added to the error code from Turbo (each is 256 times the INT24ErrorCode
value returned by DOS):
256: Attempt to write on write protected disk
512: Unknown unit [internal dos error]
768: Drive not ready [drive door open or bad drive]
1024: Unknown command [internal dos error]
1280: Data error (CRC) [bad sector or drive]
1536: Bad request structure length [internal dos error]
1792: Seek error [bad disk or drive]
2048: Unknown media type [bad disk or drive]
2304: Sector not found [bad disk or drive]
2560: Printer out of paper [anything that the printer might signal]
2816: Write fault [character device not ready]
3072: Read fault [character device not ready]
3328: General failure [several meanings]
If you need the IOResult part, use
I:=INT24Result and 255; [masks out the INT 24 code]
For the INT 24 code, use
I:=INT24Result Shr 8; [same as Div 256, except faster]
INT24Result clears both error codes, so you must assign it to a variable if
you want to extract both codes:
J:=INT24Result;
WriteLn('Turbo IOResult = ',J And 255);
WriteLn('DOS INT 24 code = ',J Shr 8); }
{ Main program. Delete next line to enable }
(**)
{ Run this with printer off (or no printer), and nothing in drive A }
Var
F: File;
I: Integer;
Procedure PrinterTest;
Begin
WriteLn(LST,'test');
I:=INT24Result;
If I<>0 Then WriteLn('Printer error: ',I)
Else WriteLn('Printer OK');
End;
Procedure FileTest;
Begin
Assign(F,'A:FILE');
{$I-} Reset(F); {$I+}
I:=INT24Result;
If I<>0 Then WriteLn('Open failure on A:FILE : INT24Result=',I)
Else WriteLn('A:FILE exists');
Close(F);
End;
Begin
INT24On;
PrinterTest;
FileTest;
PrinterTest;
INT24Off;
FileTest;
PrinterTest;
End.
(**)